/*include guards*/
#ifndef L2_CACHE_H
#define L2_CACHE_H
//standard header files
//This is the parent cache class
#include<iostream>
#include<sstream>
#include<fstream>
#include<stdio.h>

//other header files

#define M 0
#define E 1
#define S 2
#define I 3

using namespace std;
class CacheLine
{
public:
    int validbit;
// LRUBits are 0||1||2||3 with 0 most recently used
    int lruBits;
    int tag;
    int address;
    int state;//0-M 1-E 2-S 3-I
    int protocol;//0-MI 1-MSI 2-MESI
    CacheLine() {}
    virtual ~CacheLine() {}
    int MI(int operation)
    {
        if(operation == 0 || operation == 1)
            state = M;
        if(operation == 2 || operation == 3)
            state = I;

        if(state != I)
            return 1;
        else
            return 0;
    }
    int MSI(int operation)
    {
        if(state == M && operation == 0)
            state = M;
        if(state == M && operation == 1)
            state = M;
        if(state == M && operation == 2)
            state = S;
        if(state == M && operation == 3)
            state = I;
        if(state == S && operation == 0)
            state = S;
        if(state == S && operation == 1)
            state = M;
        if(state == S && operation == 2)
            state = S;
        if(state == S && operation == 3)
            state = I;
        if(state == I && operation == 0)
            state = S;
        if(state == I && operation == 1)
            state = M;
        if(state == I && operation == 2)
            state = I;
        if(state == I && operation == 3)
            state = I;

        if(state != I)
            return 1;
        else
            return 0;
    }
    int MESI(int operation, int valid)
    {
        /*
         *    * *Operation = 0- Processor Read
         *       * *Operation = 1- Processor Write*Operation = 2- Bus Read
         *          * *Operation = 3- Bus Write
         *             * */
        if(state == M && operation == 0)
            state = M;
        if(state == M && operation == 1)
            state = M;
        if(state == M && operation == 2)
            state = S;
        if(state == M && operation == 3)
            state = I;
        if(state == E && operation == 0)
            state = E;
        if(state == E && operation == 1)
            state = M;
        if(state == E && operation == 2)
            state = S;
        if(state == E && operation == 3)
            state = I;
        if(state == S && operation == 0)
            state = S;
        if(state == S && operation == 1)
            state = M;
        if(state == S && operation == 2)
            state = S;
        if(state == S && operation == 3)
            state = I;
        if(state == I && operation == 0 && valid == 0)
            state = E;
        if(state == I && operation == 0 && valid == 1)
            state = S;
        if(state == I && operation == 1)
            state = M;
        if(state == I && operation == 2)
            state = I;
        if(state == I && operation == 3)
            state = I;

        if(state != I)
            return 1;
        else
            return 0;


    }


};


#endif /* end of include guard */
